package com.dzjcloud.dzj.upms.biz.service.impl;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.dzjcloud.dzj.common.core.constant.CommonConstants;
import com.dzjcloud.dzj.common.core.enums.ResultEnum;
import com.dzjcloud.dzj.common.core.exception.HandleException;
import com.dzjcloud.dzj.common.core.utils.GetTime;
import com.dzjcloud.dzj.common.minio.service.MinioTemplate;
import com.dzjcloud.dzj.common.minio.utils.BucketUtils;
import com.dzjcloud.dzj.common.minio.utils.FileCheckUtils;
import com.dzjcloud.dzj.upms.biz.service.FileService;
import com.dzjcloud.dzj.upms.biz.utils.MinioURLUtils;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;

/**
 * <h3>dzj-cloud</h3>
 * <p>文件业务实现</p>
 *
 * @author : DongZeJian
 * @date : 2021-06-02 09:32
 **/
@Service
@Slf4j
public class FileServiceImpl implements FileService {

    @Autowired
    private MinioTemplate minioTemplate;

    @Autowired
    private MinioURLUtils minioURLUtils;

    /**
     *  单文件上传
     *
     * @param file 文件
     * @param uploadType 上传桶位置
     * @return
     */
    @Override
    public Map<String, String> uploadFileToCenter(MultipartFile file, Integer uploadType) {

        Validator.validateNotEmpty(uploadType,"位置不能为空");


        //获取bucketName 判断bucketName是否为后台指定
        String bucketName = Validator.validateNotEmpty(BucketUtils.getValue(uploadType), ResultEnum.PARAM_IS_ERROR.getMessage());

        //检查文件大小是否在指定范围内
        checkFileSize(bucketName, file);

        //更改文件名称
        String fileName = GetTime.getGuid() + StrUtil.DOT + FileUtil.extName(file.getOriginalFilename());

        //文件上传
        try {
            minioTemplate.putObject(bucketName,fileName,file.getInputStream());
        } catch (Exception e) {
            log.error("上传文件到Minio服务器异常 : {}", ExceptionUtil.stacktraceToString(e));
            throw new HandleException(ResultEnum.ERROR_CODE.getCode(), "上传文件到Minio服务器异常");
        }

        //返回路径给前端
        Map<String, String> map = Maps.newHashMap();
        map.put("fileName", fileName);
        map.put("effectiveUrl", minioTemplate.getObjectURL(bucketName, fileName, 7 * 24 * 60 * 60));
        map.put("permanentUrl", minioURLUtils.getMinioURl(fileName,uploadType));
        return map;
    }

    /**
     * 根据bucket空间判断上传文件大小限制
     *
     * @param bucketName : Minio中bucket存储空间
     * @param file       : file文件
     */
    private void checkFileSize(String bucketName, MultipartFile file) {

        switch (bucketName) {

            //upms文件大小控制在3M以内
            case CommonConstants.BUCKET_UPMS:
                Boolean checkUpmsFileSize = FileCheckUtils.checkFileSize(file.getSize(), 1, "G");
                if (!checkUpmsFileSize) {
                    throw new HandleException(ResultEnum.ERROR_CODE.getCode(), file.getOriginalFilename() + " : 文件过大 请上传3M以内的文件");
                }
                break;
            //二手房网签文件大小控制在3M以内
            case CommonConstants.BUCKET_QUESTION:
                Boolean checkStockhouseSigningFileSize = FileCheckUtils.checkFileSize(file.getSize(), 1, "G");
                if (!checkStockhouseSigningFileSize) {
                    throw new HandleException(ResultEnum.ERROR_CODE.getCode(), file.getOriginalFilename() + " : 文件过大 请上传3M以内的文件");
                }
                break;
            default:
                break;
        }
    }

    /**
     *  删除文件
     *
     * @param fileName 文件名称
     * @param uploadType 文件桶位置
     * @return
     */
    @Override
    public Boolean deletefile(String fileName, Integer uploadType) {
        //获取bucketName 判断bucketName是否为后台指定
        String bucketName = Validator.validateNotEmpty(BucketUtils.getValue(uploadType), ResultEnum.PARAM_IS_ERROR.getMessage());

        //删除文件
        try {
            minioTemplate.removeObject(bucketName, fileName);
        } catch (Exception e) {
            log.error("文件删除异常: {}", ExceptionUtil.stacktraceToString(e));
            throw new HandleException(ResultEnum.ERROR_CODE.getCode(), "文件删除异常");
        }
        return true;
    }
}
